package cn.gwm.flink.streaming.dwm.charge.support;

import cn.gwm.flink.streaming.constant.BaseFields;
import cn.gwm.flink.streaming.constant.VehicleType;
import cn.gwm.flink.streaming.dwm.charge.assist.ChargeSteadyFieldUtil;
import cn.gwm.flink.streaming.dwm.charge.model.ChargeConstant;
import cn.gwm.flink.streaming.dwm.charge.model.ChargeStateEnum;
import cn.gwm.flink.streaming.dws.reservecharge.enums.ChargeConnectTypeEnum;
import cn.hutool.json.JSONObject;
import org.apache.flink.api.common.state.ValueState;

import java.math.BigDecimal;


/**
 * @ClassName ChargeState
 * @Description 充电状态的处理
 * @Author LiangGuang
 * @Date 2023/05/10 11:23
 */
public class ChargeState {

    /**
     * 真实当前充电状态判断
     *
     * @param constant
     * @param nowData
     * @param summarState
     * @return
     * @throws Exception
     */
    public static ChargeStateEnum realState(ChargeConstant constant, JSONObject nowData, ValueState<JSONObject> summarState) throws Exception {
        // 根据充电状态字段，进行状态预判断
        ChargeStateEnum chargeState = currentChargeState(constant, nowData);

        if (ChargeStateEnum.CHARGING.equals(chargeState)) {
            // 充电中，但是需要判断是电流状态
            if (nowData.getInt(constant.getBmsBattCurr() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX) == 0) {
                // 电流大于等于0
                // 是否是因为已经满电的缘故
                if (nowData.containsKey(constant.getTboxBattSoc())) {
                    if (!BaseFields.defaultVal.equals(nowData.getStr(constant.getTboxBattSoc())) && !"0".equals(nowData.getStr(constant.getTboxBattSoc()))
                            && BigDecimal.valueOf(nowData.getDouble(constant.getTboxBattSoc()) - 1).compareTo(nowData.getBigDecimal(constant.getBmsInnerSOC())) <= 0) {
                        chargeState = ChargeStateEnum.FULLY;
                    } else {
                        chargeState = ChargeStateEnum.UNABLE;
                    }
                } else {
                    chargeState = ChargeStateEnum.UNABLE;
                }
            }
        } else if (ChargeStateEnum.FULLY.equals(chargeState)) {
            // 不到99
            if (BigDecimal.valueOf(99).compareTo(nowData.getBigDecimal(constant.getBmsInnerSOC())) > 0) {
                // 电流不为负
                if (nowData.getInt(constant.getBmsBattCurr() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX) == 0) {
                    chargeState = ChargeStateEnum.DELAY;
                } else {
                    chargeState = ChargeStateEnum.OTHER;
                }
            }
        } else if (ChargeStateEnum.SUSPEND.equals(chargeState)) {
            // 如果电量已经到99或者目标电量了，则按满电算
            if (BigDecimal.valueOf(99).compareTo(nowData.getBigDecimal(constant.getBmsInnerSOC())) < 0) {
                chargeState = ChargeStateEnum.FULLY;
            } else if (nowData.containsKey(constant.getTboxBattSoc())
                    && !BaseFields.defaultVal.equals(nowData.getStr(constant.getTboxBattSoc()))
                    && !"0".equals(nowData.getStr(constant.getTboxBattSoc()))
                    && BigDecimal.valueOf(nowData.getDouble(constant.getTboxBattSoc()) - 1).compareTo(nowData.getBigDecimal(constant.getBmsInnerSOC())) <= 0) {
                chargeState = ChargeStateEnum.FULLY;
            } else {
                // 如果本次中断之前并没有实际充过电，则当前状态改为待充电
                JSONObject summar = summarState.value();
                if (summar == null || summar.getInt(constant.getChrgLogicNum()) == 0) {
                    chargeState = ChargeStateEnum.WAIT;
                }
            }
        }
        return chargeState;
    }


    /**
     * 当前充电状态 [粗处理]
     *
     * @param constant
     * @param sourceData
     * @return
     */
    public static ChargeStateEnum currentChargeState(ChargeConstant constant, JSONObject sourceData) {
        if (VehicleType.POWER_TYPE_PHEV.equals(sourceData.getStr(BaseFields.CUSTOM_TYPE).toLowerCase())) {
            return phevChargeState(constant, sourceData);
        } else if (VehicleType.POWER_TYPE_EV.equals(sourceData.getStr(BaseFields.CUSTOM_TYPE).toLowerCase())) {
            return evChargeState(constant, sourceData);
        }
        // 非ev或者phev 不进行充电处理
        return ChargeStateEnum.END;
    }

    /**
     * ev充电状态的处理
     *
     * @param constant
     * @param sourceData
     * @return
     */
    public static ChargeStateEnum evChargeState(ChargeConstant constant, JSONObject sourceData) {
        int mc = sourceData.getInt(constant.getObcConnectStsEv() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX);
        int djcc = sourceData.getInt(constant.getObcCclineConnectSts() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX);
        int kc = sourceData.getInt(constant.getBmsDcchrgConnect() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX);
        if (mc == 0 && djcc == 0 && kc == 0) {
            // 物理断开
            return ChargeStateEnum.END;
        } else {
            if (kc == 1 && (mc == 1 || djcc == 1)) {
                // 连接出错
                return ChargeStateEnum.ERROR;
            } else if (mc == 2 || djcc == 2) {
                // 逻辑断开
                return ChargeStateEnum.LOGIC_BREAK;
            }
            if ((((mc == 1 || djcc == 1) && kc == 0) || (kc == 1 && (mc == 0 && djcc == 0)))) {
                // 正常插枪状态
                // 此处只考虑了 充电状态，在具体的业务中 需要进行 结合电流和是否充电等 进行 细致划分。
                Integer chargeSts = sourceData.getInt(constant.getBmsChrgSts() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX);
                ChargeStateEnum state;
                switch (chargeSts) {
                    case 0:
                        state = ChargeStateEnum.SUSPEND;
                        break;
                    case 1:
                        state = ChargeStateEnum.CHARGING;
                        break;
                    case 2:
                        state = ChargeStateEnum.FULLY;
                        break;
                    case 3:
                        state = ChargeStateEnum.FAULT;
                        break;
                    default:
                        state = ChargeStateEnum.OTHER;
                        break;
                }
                return state;
            }
            return ChargeStateEnum.OTHER;
        }
    }


    /**
     * 0x0:Default
     * 0x1:Charging
     * 0x2:Delaying
     * 0x3:Charge complete
     * 0x4:Charge stopped
     * 0x5: Charge initialize
     * 0x6:Fault
     * 0x7:Reserved
     * 0x8:heating（插枪仅加热）
     * 0x9:chargingandheating（充电且加热）
     *
     * @param constant
     * @param sourceData
     * @return
     */
    public static ChargeStateEnum phevChargeState(ChargeConstant constant, JSONObject sourceData) {
        int mc = sourceData.getInt(constant.getObcConnectStsEv() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX);
        int djcc = sourceData.getInt(constant.getObcCclineConnectSts() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX);
        int kc = sourceData.getInt(constant.getBmsDcchrgConnect() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX);

        if (mc == 0 && djcc == 0 && kc == 0) {
            // 物理断开
            return ChargeStateEnum.END;
        } else {
            if (kc == 1 && (mc == 1 || djcc == 1)) {
                // 连接出错
                return ChargeStateEnum.ERROR;
            } else if (mc == 2 || djcc == 2) {
                // 逻辑断开
                return ChargeStateEnum.LOGIC_BREAK;
            } else if (mc == 3 || djcc == 3) {
                // 连接出错
                return ChargeStateEnum.ERROR;
            }
            if ((((mc == 1 || djcc == 1) && kc == 0) || (kc == 1 && (mc == 0 && djcc == 0)))) {
                // 正常插枪状态
                // 此处只考虑了 充电状态，在具体的业务中 需要进行 结合电流和是否充电等 进行 细致划分。
                Integer chargeSts = sourceData.getInt(constant.getBmsChrgSts() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX);

                if (chargeSts == 0 || chargeSts == 7) {
                    return ChargeStateEnum.SUSPEND;
                } else if (chargeSts == 1) {
                    return ChargeStateEnum.CHARGING;
                } else if (chargeSts == 2) {
                    return ChargeStateEnum.DELAY;
                } else if (chargeSts == 3) {
                    return ChargeStateEnum.FULLY;
                } else if (chargeSts == 4 || chargeSts == 6) {
                    return ChargeStateEnum.FAULT;
                } else if (chargeSts == 5) {
                    return ChargeStateEnum.WAIT;
                } else if (chargeSts == 8) {
                    return ChargeStateEnum.PREHEAT;
                } else if (chargeSts == 9) {
                    return ChargeStateEnum.CHARGING_HEATING;
                }
            }
            return ChargeStateEnum.OTHER;
        }
    }


    public static ChargeConnectTypeEnum connectType(ChargeConstant constant, JSONObject sourceData) {
        int mc = sourceData.getInt(constant.getObcConnectStsEv() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX);
        int djcc = sourceData.getInt(constant.getObcCclineConnectSts() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX);
        int kc = sourceData.getInt(constant.getBmsDcchrgConnect() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX);
        // 此前过滤了 -999999
        if (kc != 0 && (mc == 0 && djcc == 0)) {
            return ChargeConnectTypeEnum.QUICK;
        }
        if (kc == 0 && (mc != 0 || djcc != 0)) {
            return ChargeConnectTypeEnum.SLOW;
        }
        return ChargeConnectTypeEnum.UNKNOWN;
    }


}
